﻿using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;

namespace VolunteerHubAdapter
{
public sealed class PasswordBoxAssistant
{
    private PasswordBoxAssistant()
    {
    }

    public static readonly DependencyProperty BoundPassword = DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));

    public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached("BindPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged));

    private static readonly DependencyProperty UpdatingPassword = DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false));
    private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        PasswordBox box = d as PasswordBox;

        // only handle this event when the property is attached to a PasswordBox
        // and when the BindPassword attached property has been set to true
        if (d == null || !GetBindPassword(d))
        {
            return;
        }

        // avoid recursive updating by ignoring the box's changed event
        box.PasswordChanged -= HandlePasswordChanged;

        string newPassword = (string)e.NewValue;

        if (!GetUpdatingPassword(box))
        {
            box.Password = newPassword;
        }

        box.PasswordChanged += HandlePasswordChanged;
    }

    private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        // when the BindPassword attached property is set on a PasswordBox,
        // start listening to its PasswordChanged event

        PasswordBox box = dp as PasswordBox;

        if (box == null)
        {
            return;
        }

        bool wasBound = Convert.ToBoolean(e.OldValue);
        bool needToBind = Convert.ToBoolean(e.NewValue);

        if (wasBound)
        {
            box.PasswordChanged -= HandlePasswordChanged;
        }

        if (needToBind)
        {
            box.PasswordChanged += HandlePasswordChanged;
        }
    }

    private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
    {
        PasswordBox box = sender as PasswordBox;

        // set a flag to indicate that we're updating the password
        SetUpdatingPassword(box, true);
        // push the new password into the BoundPassword property
        SetBoundPassword(box, box.Password);
        SetUpdatingPassword(box, false);
    }

    public static void SetBindPassword(DependencyObject dp, bool value)
    {
        dp.SetValue(BindPassword, value);
    }

    public static bool GetBindPassword(DependencyObject dp)
    {
        return Convert.ToBoolean(dp.GetValue(BindPassword));
    }

    public static string GetBoundPassword(DependencyObject dp)
    {
        return (string)dp.GetValue(BoundPassword);
    }

    public static void SetBoundPassword(DependencyObject dp, string value)
    {
        dp.SetValue(BoundPassword, value);
    }

    private static bool GetUpdatingPassword(DependencyObject dp)
    {
        return Convert.ToBoolean(dp.GetValue(UpdatingPassword));
    }

    private static void SetUpdatingPassword(DependencyObject dp, bool value)
    {
        dp.SetValue(UpdatingPassword, value);
    }
}
}
